home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
SNNSV32.ZIP
/
SNNSv3.2
/
kernel
/
sources
/
kr_newpattern.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-25
|
82KB
|
2,794 lines
/*****************************************************************************
FILE : kr_newpattern.c
SHORTNAME : newpattern
SNNS VERSION : 3.2
PURPOSE : handling of new pattern files;
NOTES :
AUTHOR : Michael Vogt
DATE : 10.9.93
CHANGED BY :
IDENTIFICATION : @(#)kr_newpattern.c 1.6 4/21/94
SCCS VERSION : 1.6
LAST CHANGE : 4/21/94
Copyright (c) 1990-1994 SNNS Group, IPVR, Univ. Stuttgart, FRG
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/time.h>
#include "kr_typ.h"
#include "glob_typ.h"
#include "kr_mac.h"
#ifndef rand
#include "random.h" /* Randomize Library Function Prototypes */
#endif
#include "kernel.h"
#include "kr_const.h"
#include "kr_pat_scan.h"
#include "kr_pat_parse.h"
#include "kr_newpattern.ph"
/*****************************************************************************
FUNCTIONS WHICH ARE CALLED BY THE KERNEL USER INTERFACE TO PERFORM
THE KERNEL INTERFACE OF THE NEW PATTERN MANAGEMENT
******************************************************************************/
/*****************************************************************************
FUNCTION : kr_npui_setCurrPatSet
PURPOSE : determines the number of the current pattern set (in
kernel terminology) numbering starts with 0
RETURNS : kernel error code
NOTES :
UPDATE :
******************************************************************************/
krui_err kr_npui_setCurrPatSet(int number)
{
if (number<0 || number>=npui_number_pat_sets)
return KRERR_NP_NO_SUCH_PATTERN_SET;
npui_curr_pat_set = number;
npui_curr_pattern = 1;
npui_train_defined = FALSE;
npui_show_defined = FALSE;
np_abs_count_valid = FALSE;
np_sub_pat_sizes_valid = FALSE;
return KRERR_NO_ERROR;
}
/*****************************************************************************
FUNCTION : kr_npui_deletePatSet
PURPOSE : deletes the specified pattern set from memory and
undefines the current pattern set, pattern, training
scheme and display scheme
RETURNS : kernel error code
NOTES :
UPDATE :
******************************************************************************/
krui_err kr_npui_deletePatSet(int number)
{
int i;
int pat_set;
if (number<0 || number>=npui_number_pat_sets)
return KRERR_NP_NO_SUCH_PATTERN_SET;
pat_set = npui_pat_sets[number];
for (i=number; i<npui_number_pat_sets-1; i++)
npui_pat_sets[i] = npui_pat_sets[i+1];
npui_number_pat_sets--;
npui_curr_pat_set = -1;
npui_curr_pattern = -1;
npui_train_defined = FALSE;
npui_show_defined = FALSE;
np_abs_count_valid = FALSE;
np_sub_pat_sizes_valid = FALSE;
return kr_np_DeletePatternSet(pat_set);
}
/*****************************************************************************
FUNCTION : kr_npui_GetPatInfo
PURPOSE : retrieves all available information concerning the
current pattern set and the current pattern which both
must be defined. The given parameter fields are filled
with the information.
RETURNS : kernel error code
NOTES :
UPDATE :
******************************************************************************/
krui_err kr_npui_GetPatInfo(pattern_set_info *set_info,
pattern_descriptor *pat_info)
{
pattern_descriptor *int_pat_info;
krui_err err_code;
if (npui_curr_pat_set == -1)
return KRERR_NP_NO_CURRENT_PATTERN_SET;
if (npui_curr_pattern == -1)
return KRERR_NP_NO_CURRENT_PATTERN;
err_code = kr_np_GetInfo(npui_pat_sets[npui_curr_pat_set],
set_info);
if (err_code != KRERR_NO_ERROR)
return err_code;
err_code = kr_np_GetDescriptor(npui_pat_sets[npui_curr_pat_set],
npui_curr_pattern-1,
&int_pat_info);
if (err_code != KRERR_NO_ERROR)
return err_code;
*pat_info = *int_pat_info;
return KRERR_NO_ERROR;
}
/*****************************************************************************
FUNCTION : kr_npui_DefShowSubPat
PURPOSE : Define the display scheme:
Size and position of a sub pattern for the current
pattern in the current pattern set is defined. <insize>
is a pointer to an array of integer values which define
the dimensional sizes of the input sub pattern. <inpos>
is a pointer to an array of integer values which defines
the offset (position) of this sub pattern inside the
pattern. <outsize> and <outpos> are used to define the
respective output sub pattern
RETURNS : kernel error code
NOTES :
UPDATE :
******************************************************************************/
krui_err kr_npui_DefShowSubPat(int *insize, int *outsize,
int *inpos, int *outpos)
{
krui_err err_code;
pattern_descriptor *pattern;
int i;
npui_show_defined = FALSE;
if (npui_curr_pat_set == -1)
return KRERR_NP_NO_CURRENT_PATTERN_SET;
if (npui_curr_pattern == -1)
return KRERR_NP_NO_CURRENT_PATTERN;
err_code = kr_np_GetDescriptor(npui_pat_sets[npui_curr_pat_set],
npui_curr_pattern-1,
&pattern);
if (err_code != KRERR_NO_ERROR)
return err_code;
for (i=0; i<pattern->input_dim; i++)
{
if ((pattern->input_dim_sizes)[i] < insize[i] + inpos[i] - 1)
err_code = KRERR_NP_DIMENSION;
}
for (i=0; i<pattern->output_dim; i++)
{
if ((pattern->output_dim_sizes)[i] < outsize[i] + outpos[i] - 1)
err_code = KRERR_NP_DIMENSION;
}
if (err_code != KRERR_NO_ERROR)
return err_code;
memcpy(npui_insize, insize, MAX_NO_OF_VAR_DIM * sizeof(int));
memcpy(npui_outsize, outsize, MAX_NO_OF_VAR_DIM * sizeof(int));
memcpy(npui_inpos, inpos, MAX_NO_OF_VAR_DIM * sizeof(int));
memcpy(npui_outpos, outpos, MAX_NO_OF_VAR_DIM * sizeof(int));
for (i=0; i<MAX_NO_OF_VAR_DIM; i++)
{
npui_inpos[i]--;
npui_outpos[i]--;
}
npui_show_defined = TRUE;
return KRERR_NO_ERROR;
}
/*****************************************************************************
FUNCTION : kr_npui_DefTrainSubPat
PURPOSE : Define the training scheme:
Size and step size of sub pattern for the current pattern
in the current pattern set is defined for training and
testing. <insize> is a pointer to an array of integer
values which define the dimensional sizes of the input sub
pattern. <instep> is a pointer to an array of integer
values which defines the step size which is used to move
the sub pattern over the pattern.
<outsize> and <outpos> are used to define the respective
output sub pattern.
<max_n_pos> (if not NULL) returns the number of valid
input sub pattern positions for the current pattern and
the given training scheme.
RETURNS : kernel error code
NOTES :
UPDATE :
******************************************************************************/
krui_err kr_npui_DefTrainSubPat(int *insize, int *outsize,
int *instep, int *outstep, int *max_n_pos)
{
krui_err err_code;
int n;
pattern_descriptor *p;
npui_train_defined = FALSE;
np_abs_count_valid = FALSE;
np_sub_pat_sizes_valid = FALSE;
if (npui_curr_pat_set == -1)
return KRERR_NP_NO_CURRENT_PATTERN_SET;
if (npui_curr_pattern == -1)
return KRERR_NP_NO_CURRENT_PATTERN;
memcpy(npui_insize, insize, MAX_NO_OF_VAR_DIM * sizeof(int));
memcpy(npui_outsize, outsize, MAX_NO_OF_VAR_DIM * sizeof(int));
memcpy(npui_instep, instep, MAX_NO_OF_VAR_DIM * sizeof(int));
memcpy(npui_outstep, outstep, MAX_NO_OF_VAR_DIM * sizeof(int));
err_code =
kr_np_DefineSubPatternOrdering(npui_pat_sets[npui_curr_pat_set],
TRUE, npui_insize, npui_instep);
if (err_code != KRERR_NO_ERROR)
return err_code;
err_code =
kr_np_DefineSubPatternOrdering(npui_pat_sets[npui_curr_pat_set],
FALSE, npui_outsize,
npui_outstep);
if (err_code != KRERR_NO_ERROR)
return err_code;
npui_train_defined = TRUE;
if (max_n_pos != (int *) NULL)
{
err_code = kr_np_GetDescriptor(npui_pat_sets[npui_curr_pat_set],
npui_curr_pattern-1, &p);
if (err_code != KRERR_NO_ERROR)
return err_code;
if (!kr_np_gen_sub_pos(p->input_dim, &n, p->input_dim_sizes,
npui_insize, npui_instep, (int *) NULL,
TRUE))
return KRERR_NP_DIMENSION;
*max_n_pos = n;
}
return KRERR_NO_ERROR;
}
/*****************************************************************************
FUNCTION : kr_npui_AlignSubPat
PURPOSE : Align the position of a sub pattern:
Using the current training scheme and the current pattern
of the current pattern set, the given position of an
input sub pattern <inpos> and the given position of the
corresponding output sub pattern <outpos> is aligned to fit
the currently defined training scheme.
E.g. if the training scheme defines a step width of 5 for
a specific dimension, only the positions 0, 5, 10, 15 ...
are valid positions for a sub pattern.
The position of each dimension is aligned independently
from all other dimensions by moving to the next valid
position which is lower or equal to the given position.
<no> (if not NULL) returns the number of the sub pattern
which corresponds to the new aligned position which is
returned in place (<inpos> <outpos>).
RETURNS : kernel error code
NOTES :
UPDATE :
******************************************************************************/
krui_err kr_npui_AlignSubPat(int *inpos, int *outpos, int *no)
{
krui_err err_code;
pattern_descriptor *p;
int pos;
int i;
if (npui_curr_pat_set == -1)
return KRERR_NP_NO_CURRENT_PATTERN_SET;
if (npui_curr_pattern == -1)
return KRERR_NP_NO_CURRENT_PATTERN;
if (npui_train_defined == FALSE)
return KRERR_NP_NO_TRAIN_SCHEME;
err_code = kr_np_GetDescriptor(npui_pat_sets[npui_curr_pat_set],
npui_curr_pattern-1, &p);
if (err_code != KRERR_NO_ERROR)
return err_code;
/* enumeration starts with 0, not with 1 */
for (i=0; i< p->input_dim; i++)
inpos[i] -= 1;
/* align the position of the input sub pattern */
if (!kr_np_align_sub_pos(p->input_dim, &pos,
p->input_dim_sizes, npui_insize,
npui_instep, inpos))
{
for (i=0; i< p->input_dim; i++)
inpos[i] = 1;
return KRERR_NP_DIMENSION;
}
/* now enumeration starts with 1 again */
for (i=0; i< p->input_dim; i++)
inpos[i] += 1;
/* find the output sub pattern which is related to the aligned */
/* input sub pattern */
if (!kr_np_gen_sub_pos(p->output_dim, &pos,
p->output_dim_sizes, npui_outsize,
npui_outstep, outpos, FALSE))
{
for (i=0; i< p->output_dim; i++)
outpos[i] = 1;
return KRERR_NP_DIMENSION;
}
/* now enumeration starts with 1 again */
for (i=0; i< p->output_dim; i++)
outpos[i] += 1;
/* return the absolute position */
*no = pos+1;
return KRERR_NO_ERROR;
}
/*****************************************************************************
FUNCTION : kr_npui_allocNewPatternSet
PURPOSE : Allocate an (additional) empty pattern set: A new pattern
set is allocated if the maximum number of loaded pattern sets
(NO_OF_PAT_SETS) is not exceeded. The corresponding pattern set
handle is returned in <set_no>. The new allocated pattern set
becomes the current set. There is no current pattern defined.
Training scheme and display scheme both become undefined.
NOTES :
RETURNS :
UPDATE :
******************************************************************************/
krui_err kr_npui_allocNewPatternSet(int *set_no)
{
int pat_set;
krui_err err_code;
if (npui_number_pat_sets >= NO_OF_PAT_SETS)
return KRERR_NP_NO_MORE_ENTRIES;
/* allocate pattern set with zero pattern */
err_code = kr_np_AllocatePatternSet(&pat_set, 0);
if (err_code == KRERR_NO_ERROR)
{
npui_curr_pat_set = npui_number_pat_sets;
npui_number_pat_sets++;
npui_curr_pattern = -1;
npui_pat_sets[npui_curr_pat_set] = pat_set;
*set_no = npui_curr_pat_set;
npui_train_defined = FALSE;
npui_show_defined = FALSE;
np_abs_count_valid = FALSE;
np_sub_pat_sizes_valid = FALSE;
}
return err_code;
}
/*****************************************************************************
FUNCTION : kr_npui_loadNewPatterns
PURPOSE : Load an (additional) pattern file:
The file with name <filename> is loaded into memory if
existent and if the maximum number of loaded pattern sets
(NO_OF_PAT_SETS) is not exceeded. The corresponding
pattern set handle is returned in <set_no>.
The new loaded pattern set becomes the current set. The
first pattern inside this set becomes the current
pattern. Training scheme and display scheme both become
undefined.
RETURNS : kernel error code
NOTES :
UPDATE :
******************************************************************************/
krui_err kr_npui_loadNewPatterns(char *filename, int *set_no)
{
FILE *infile;
int pat_set;
int read_from_pipe = 0;
char *buf;
krui_err err_code;
if (npui_number_pat_sets >= NO_OF_PAT_SETS)
return KRERR_NP_NO_MORE_ENTRIES;
if (access(filename, F_OK) != 0)
return KRERR_FILE_OPEN;
if (strcmp(&filename[strlen(filename)-2], ".Z") == 0)
{
buf = (char *) malloc(strlen(filename)+strlen("zcat ")+1);
if (buf == (char *) NULL)
return KRERR_INSUFFICIENT_MEM;
sprintf(buf, "zcat %s", filename);
infile = popen(buf,"r");
read_from_pipe = 1;
}
else
infile = fopen(filename, "r");
if (infile == (FILE *) NULL)
return KRERR_FILE_OPEN;
err_code = kr_np_LoadPatternFile(infile, &pat_set);
if (err_code == KRERR_NO_ERROR)
{
npui_curr_pat_set = npui_number_pat_sets;
npui_number_pat_sets++;
npui_curr_pattern = 1;
npui_pat_sets[npui_curr_pat_set] = pat_set;
*set_no = npui_curr_pat_set;
npui_train_defined = FALSE;
npui_show_defined = FALSE;
np_abs_count_valid = FALSE;
np_sub_pat_sizes_valid = FALSE;
}
if (read_from_pipe)
{
pclose(infile);
free(buf);
}
else
fclose(infile);
return err_code;
}
/*****************************************************************************
FUNCTION : kr_npui_saveNewPatterns
PURPOSE : The given pattern set <set_no> is written to file
<filename> in new style format. No side effects.
RETURNS : kernel error code
NOTES :
UPDATE :
******************************************************************************/
krui_err kr_npui_saveNewPatterns(char *filename, int set_no)
{
FILE *outfile;
krui_err err_code;
if (set_no<0 || set_no>=npui_number_pat_sets)
return KRERR_NP_NO_SUCH_PATTERN_SET;
outfile = fopen(filename, "w");
if (outfile == (FILE *) NULL)
return KRERR_FILE_OPEN;
err_code = kr_np_SavePatternFile(outfile, npui_pat_sets[set_no]);
fclose(outfile);
return err_code;
}
/*****************************************************************************
FUNCTION : kr_npui_GetShapeOfSubPat
PURPOSE : Get the shape of a sub pattern which is specified by a
number:
After kr_npui_DefTrainSubPat has been called for the
current pattern set and a current pattern is defined,
this function retrieves the <n_pos>th valid sub pattern
pair which matches the defined training scheme. Size and
position of the sub pattern pair is returned in <insize>
<inpos> <outsize> and <outpos> which are all pointer to
integer arrays.
RETURNS : kernel error code
NOTES :
UPDATE :
******************************************************************************/
krui_err kr_npui_GetShapeOfSubPat(int *insize, int *outsize,
int *inpos, int *outpos, int n_pos)
{
int sp[MAX_NO_OF_VAR_DIM];
pattern_descriptor *p;
krui_err err_code;
int n;
int i;
if (npui_curr_pat_set == -1)
return KRERR_NP_NO_CURRENT_PATTERN_SET;
if (npui_curr_pattern == -1)
return KRERR_NP_NO_CURRENT_PATTERN;
if (!npui_train_defined)
return KRERR_NP_NO_TRAIN_SCHEME;
err_code = kr_np_GetDescriptor(npui_pat_sets[npui_curr_pat_set],
npui_curr_pattern-1, &p);
if (err_code != KRERR_NO_ERROR)
return err_code;
n = n_pos-1;
if (!kr_np_gen_sub_pos(p->input_dim, &n, p->input_dim_sizes,
npui_insize, npui_instep, sp, FALSE))
return KRERR_NP_NO_SUCH_PATTERN;
memcpy((char *) inpos, (char *) sp, p->input_dim * sizeof(int));
for (i=0; i<p->input_dim; i++)
inpos[i]++;
if (!kr_np_gen_sub_pos(p->output_dim, &n, p->output_dim_sizes,
npui_outsize, npui_outstep, sp, FALSE))
return KRERR_NP_NO_SUCH_PATTERN;
memcpy((char *) outpos, (char *) sp, p->output_dim *sizeof(int));
for (i=0; i<p->output_dim; i++)
outpos[i]++;
memcpy((char *) insize, (char *) npui_insize, p->input_dim *sizeof(int));
memcpy((char *) outsize, (char *) npui_outsize, p->input_dim *sizeof(int));
return KRERR_NO_ERROR;
}
/*****************************************************************************
FUNCTIONS WHICH ARE CALLED BY OTHER KERNEL FUNCTIONS LIKE TRAINING
AND INITIALIZATION FUNCTIONS:
******************************************************************************/
/*****************************************************************************
FUNCTION : kr_np_pattern
PURPOSE : multiple pattern handling functions depending on mode and mode1
RETURNS : result, depending on operation or kernel error code
NOTES : KernelErrorCode is set to the valid kernel error code
UPDATE :
******************************************************************************/
int kr_np_pattern(int mode ,int mode1 ,int pattern_no)
{
int return_code;
int new_pattern;
pattern_set_info info;
return_code = (int) (KernelErrorCode = KRERR_NO_ERROR);
if (npui_curr_pat_set == -1)
{
KernelErrorCode = KRERR_NP_NO_CURRENT_PATTERN_SET;
return (int) KernelErrorCode;
}
/* for some modes, test current pattern definition */
switch (mode)
{
case PATTERN_GET: /* returns the current pattern */
case PATTERN_DELETE: /* delete the current pattern pair */
case PATTERN_MODIFY: /* modify the current pattern pair */
case PATTERN_SHOW: /* show pattern */
if (npui_curr_pattern == -1 && mode != PATTERN_SET)
{
KernelErrorCode = KRERR_NP_NO_CURRENT_PATTERN;
return (int) KernelErrorCode;
}
default:
break;
}
switch (mode)
{
case PATTERN_SET: /* set the current pattern */
if (pattern_no < 1 || pattern_no >
np_info[npui_pat_sets[npui_curr_pat_set]].number_of_pattern)
{
return_code = (int) (KernelErrorCode = KRERR_PATTERN_NO);
npui_curr_pattern = -1;
}
else
npui_curr_pattern = pattern_no;
break;
case PATTERN_GET: /* returns the current pattern */
return_code = npui_curr_pattern;
break;
case PATTERN_DELETE: /* delete the current pattern pair */
return_code = kr_np_DeletePattern(npui_pat_sets[npui_curr_pat_set],
npui_curr_pattern-1);
npui_curr_pattern = -1;
break;
case PATTERN_MODIFY: /* modify the current pattern pair */
return_code = (int) (KernelErrorCode = kr_np_modifyPattern());
break;
case PATTERN_SHOW: /* show pattern */
return_code = (int) (KernelErrorCode = kr_np_showPatternSTD(mode1));
break;
case PATTERN_NEW: /* new pattern */
/* before creating a new pattern, first ensure that new pattern */
/* fits into existing set */
return_code = kr_np_GetInfo(npui_pat_sets[npui_curr_pat_set], &info);
if (return_code != KRERR_NO_ERROR)
break;
(void) kr_IOCheck();
if (NoOfInputUnits == 0)
{
return_code = KernelErrorCode = KRERR_NO_INPUT_UNITS;
break;
}
if (info.number_of_pattern > 0)
{
if (info.in_number_of_dims != 0 ||
info.out_number_of_dims != 0 ||
info.in_fixsize != NoOfInputUnits ||
info.out_fixsize != NoOfOutputUnits)
{
/* creation of variable sized patterns is not possible */
/* also the new pattern must be of equal size compared to */
/* existing pattern */
return_code = KRERR_NP_INCOMPATIBLE_NEW;
break;
}
}
return_code = KernelErrorCode =
kr_np_AddPattern(npui_pat_sets[npui_curr_pat_set], &new_pattern);
if (return_code != KRERR_NO_ERROR)
break;
npui_curr_pattern = new_pattern + 1;
return_code = (int) (KernelErrorCode = kr_np_modifyPattern());
if (return_code != KRERR_NO_ERROR)
{
(void) kr_np_DeletePattern(npui_pat_sets[npui_curr_pat_set],
npui_curr_pattern-1);
npui_curr_pattern = -1;
}
break;
case PATTERN_DELETE_ALL: /* delete all pattern */
break;
case PATTERN_SHUFFLE_ON: /* shuffle pattern */
npui_shuffle_pattern = TRUE;
break;
case PATTERN_SHUFFLE_OFF: /* shuffle pattern off */
npui_shuffle_pattern = FALSE;
break;
case PATTERN_SET_NUMBER:
break;
case PATTERN_GET_NUMBER:
return_code =
np_info[npui_pat_sets[npui_curr_pat_set]].number_of_pattern;
break;
case PATTERN_SUB_SHUFFLE_ON:
npui_shuffle_sub_pattern = TRUE;
break;
case PATTERN_SUB_SHUFFLE_OFF:
npui_shuffle_sub_pattern = FALSE;
break;
case GET_SHUFFLE_FLAG:
return_code = npui_shuffle_pattern;
break;
case GET_SUB_SHUFFLE_FLAG:
return_code = npui_shuffle_sub_pattern;
break;
default:
KernelErrorCode = KRERR_PARAMETERS;
}
return return_code;
}
/*****************************************************************************
FUNCTION : kr_initSubPatternOrder
PURPOSE : The sub pattern ordering for the current pattern set is
reset for the next training or initialization run. During
this run all sub patterns from pattern <start> up to
pattern <end> are generated according to current shuffle
flags for patterns and sub patterns.
kr_getSubPatByOrder is to be called to get the next sub
pattern number during the run (see below)
RETURNS : kernel error code
NOTES :
UPDATE :
******************************************************************************/
krui_err kr_initSubPatternOrder(int start, int end)
{
int pat_set;
int n_sub;
if (!npui_train_defined)
return KRERR_NP_NO_TRAIN_SCHEME;
pat_set = npui_pat_sets[npui_curr_pat_set];
if (!kr_np_allocate_pat_train_entries(np_info[pat_set].number_of_pattern))
return KRERR_INSUFFICIENT_MEM;
if (npui_shuffle_pattern && npui_shuffle_sub_pattern)
{
np_random_train_number = kr_TotalNoOfSubPatPairs();
np_next_train_random = 0;
return KRERR_NO_ERROR;
}
kr_np_order_pat_entries(start, end);
np_next_train_pat = 0;
np_current_pattern =
&(np_pat_sets[pat_set][np_pat_train_order[0]]);
kr_np_gen_sub_pos(np_current_pattern -> input_dim, &n_sub,
np_current_pattern -> input_dim_sizes, np_t_insize,
np_t_instep, NULL, TRUE);
if (!kr_np_allocate_sub_pat_train_entries(n_sub))
return KRERR_INSUFFICIENT_MEM;
kr_np_order_sub_pat_entries(0, n_sub-1);
np_next_train_sub_pat = 0;
return KRERR_NO_ERROR;
}
/*****************************************************************************
FUNCTION : kr_getSubPatternByOrder
PURPOSE : According to the last call to kr_initSubPatternOrder, the
last call to this function and the shuffle flags, the next position
of pattern and sub pattern is determined. This numbers are returned
in <pattern> and <sub> (beginning with 0).
RETURNS : If there are no more sub pattern avaliable the return
value is FALSE, otherwise TRUE.
NOTES :
UPDATE :
******************************************************************************/
bool kr_getSubPatternByOrder(int *pattern, int *sub)
{
int n_sub;
if (npui_shuffle_pattern && npui_shuffle_sub_pattern)
{
if (np_next_train_random == -1)
return FALSE;
if (++np_next_train_random >= np_random_train_number)
np_next_train_random = -1;
return (kr_getSubPatternByNo(pattern, sub,
lrand48() % np_random_train_number));
}
if (np_next_train_pat == -1)
return FALSE;
*pattern = np_pat_train_order[np_next_train_pat];
*sub = np_sub_pat_train_order[np_next_train_sub_pat];
np_next_train_sub_pat++;
if (np_next_train_sub_pat >= np_sub_pat_train_number)
{
np_next_train_pat++;
if (np_next_train_pat >= np_pat_train_number)
{
np_next_train_pat = -1;
return TRUE;
}
np_current_pattern =
&(np_pat_sets[npui_pat_sets[npui_curr_pat_set]]
[np_pat_train_order[np_next_train_pat]]);
kr_np_gen_sub_pos(np_current_pattern -> input_dim, &n_sub,
np_current_pattern -> input_dim_sizes, np_t_insize,
np_t_instep, NULL, TRUE);
if (!kr_np_allocate_sub_pat_train_entries(n_sub))
{
KernelErrorCode = KRERR_INSUFFICIENT_MEM;
return FALSE;
}
kr_np_order_sub_pat_entries(0, n_sub-1);
np_next_train_sub_pat = 0;
}
return TRUE;
}
/*****************************************************************************
FUNCTION : kr_getSubPatternByNo
PURPOSE : According to the current pattern set, the position of the
<n>th sub pattern is determined and returned in <pattern> (the
pattern which includes the subpattern) and <sub> (the sub pattern
inside the pattern) (beginning with 0).
This function does not effect the ordering of the function
kr_getSubPatByOrder. <n> ranges from 0 to kr_TotalNoOfSubPatPairs()-1.
RETURNS : If the sub pattern is available, TRUE is returned,
otherwise FALSE.
NOTES :
UPDATE :
******************************************************************************/
bool kr_getSubPatternByNo(int *pattern, int *sub, int n)
{
register int ts;
register int tp;
register int low, high, mid;
ts = kr_TotalNoOfSubPatPairs();
if (n<0 || n>=ts)
return FALSE;
tp = np_info[npui_pat_sets[npui_curr_pat_set]].number_of_pattern;
if (tp == 1)
/* only one pattern present, sub pattern must be here */
high = 0;
else
{
/* more than one pattern present.... */
/* first try to find the right position by a direct jump */
high = (n*tp)/ts;
if (np_abs_count[high] <= n || (high != 0 && np_abs_count[high-1] > n))
{
/* direct jump was not sucessfull, now perform binary search */
low = 0;
high = tp-1;
while (low < high)
{
mid = (high+low)/2;
if (np_abs_count[mid] > n)
high = mid;
else
low = mid+1;
}
}
}
/* now high gives the index of the pattern where the sub pattern is in */
*pattern = high;
/* calculate the position of the sub pattern inside the found pattern */
if (high != 0)
*sub = n - np_abs_count[high-1];
else
*sub = n;
return TRUE;
}
/*****************************************************************************
FUNCTION : kr_TotalNoOfSubPatPairs
PURPOSE : This function returns the total number of available sub
patterns for the current pattern set or 0 if no pattern set is
defined. The result is the sum of the numbers of subpattern for all
patterns in the current set.
RETURNS : number of sub pattern or 0
NOTES :
UPDATE :
******************************************************************************/
int kr_TotalNoOfSubPatPairs(void)
{
int n;
int i;
int sum;
int n_sub;
pattern_descriptor *pat;
if (np_abs_count_valid)
return np_abs_count_No;
if (npui_curr_pat_set == -1)
return 0;
n = np_info[npui_pat_sets[npui_curr_pat_set]].number_of_pattern;
if (n > np_abs_count_size)
{
if (np_abs_count != (int *) NULL)
free(np_abs_count);
np_abs_count_size = 0;
np_abs_count = (int *) malloc(n * sizeof(int));
if (np_abs_count == (int *) NULL && n != 0)
return 0;
np_abs_count_size = n;
}
pat = np_pat_sets[npui_pat_sets[npui_curr_pat_set]];
sum = 0;
for (i=0; i<n; i++)
{
kr_np_gen_sub_pos(pat -> input_dim, &n_sub,
pat -> input_dim_sizes, np_t_insize,
np_t_instep, NULL, TRUE);
sum += n_sub;
np_abs_count[i] = sum;
pat++;
}
np_abs_count_No = sum;
np_abs_count_valid = TRUE;
return np_abs_count_No;
}
/*****************************************************************************
FUNCTION : kr_NoOfSubPatPairs
PURPOSE : This function returns the number of available sub patterns
for the pattern <pattern> of the current pattern set or 0 if this
pattern is not defined.
RETURNS :
NOTES :
UPDATE :
******************************************************************************/
int kr_NoOfSubPatPairs(int pattern)
{
register int ps;
if (!np_abs_count_valid)
{
if (kr_TotalNoOfSubPatPairs() == 0)
return 0;
}
if (pattern<0 ||
pattern > np_info[npui_pat_sets[npui_curr_pat_set]].number_of_pattern)
return 0;
ps = np_abs_count[pattern];
if (pattern == 0)
return ps;
else
return (ps - np_abs_count[pattern-1]);
}
/*****************************************************************************
FUNCTION : kr_AbsPosOfFirstSubPat
PURPOSE : This function returns the absolute position of the first
sub pattern of pattern <pattern> in the current pattern set. This
position is defined as the Sum of kr_NoOfSubPatPairs(i) where i runs
from 0 to <pattern>-1. The absolute position of the first sub
pattern of pattern 0 is 0. The returned value may be used as
argument for the function kr_getSubPatternByNo.
RETURNS :
NOTES :
UPDATE :
******************************************************************************/
int kr_AbsPosOfFirstSubPat(int pattern)
{
if (!np_abs_count_valid)
{
if (kr_TotalNoOfSubPatPairs() == 0)
return 0;
}
if (pattern <= 0 ||
pattern > np_info[npui_pat_sets[npui_curr_pat_set]].number_of_pattern)
return 0;
return np_abs_count[pattern-1];
}
/*****************************************************************************
FUNCTION : kr_TotalNoOfPattern
PURPOSE : This function returns the total number of available
patterns for the current pattern set or 0 if no pattern set is
defined.
RETURNS : number of pattern or 0
NOTES :
UPDATE :
******************************************************************************/
int kr_TotalNoOfPattern(void)
{
if (npui_curr_pat_set == -1)
return 0;
return np_info[npui_pat_sets[npui_curr_pat_set]].number_of_pattern;
}
/*****************************************************************************
FUNCTION : kr_getSubPatData
PURPOSE : For the current pattern set and the specified sub pattern
size, the data array of the <sub_no>th sub pattern of the <pat_no>th
pattern is returned. io_type spcifies whether the input (INPUT) or
output (OUTPUT) data is requested. If <size> is != NULL the size of
the data array is returned is this parameter.
RETURNS : The function returns a pointer to the data array (type
Patterns) or NULL if an error occured.
NOTES : KernelErrorCode is set if an error occured
UPDATE :
******************************************************************************/
Patterns kr_getSubPatData(int pat_no, int sub_no, int io_type, int *size)
{
int set;
pattern_descriptor *pat;
int subpos[MAX_NO_OF_VAR_DIM];
float *data;
krui_err err;
static float dummy_data = 0.0;
#ifdef DEBUG_PATTERN
fprintf(stderr, "pattern %d sub %d\n", pat_no, sub_no);
#endif
set = npui_pat_sets[npui_curr_pat_set];
pat = np_pat_sets[set];
if (pat_no >= np_info[set].number_of_pattern)
return (Patterns) NULL;
pat += pat_no;
np_current_pattern = pat;
switch (io_type)
{
case INPUT:
if (!kr_np_gen_sub_pos(pat->input_dim, &sub_no, pat->input_dim_sizes,
np_t_insize, np_t_instep, subpos, FALSE))
{
KernelErrorCode = KRERR_NP_NO_SUCH_PATTERN;
return (Patterns) NULL;
}
if ((err = kr_np_GetSubPat(TRUE, subpos, np_t_insize, &data, size))
!= KRERR_NO_ERROR)
{
KernelErrorCode = err;
return (Patterns) NULL;
}
return (Patterns) data;
break;
case OUTPUT:
if (!kr_np_gen_sub_pos(pat->output_dim, &sub_no, pat->output_dim_sizes,
np_t_outsize, np_t_outstep, subpos, FALSE))
{
KernelErrorCode = KRERR_NP_NO_SUCH_PATTERN;
return (Patterns) NULL;
}
if ((err = kr_np_GetSubPat(FALSE, subpos, np_t_outsize, &data, size))
!= KRERR_NO_ERROR)
{
KernelErrorCode = err;
return (Patterns) NULL;
}
/* kr_np_GetSubPat reports no error if a zero length output sub */
/* pattern is requested. Instead a NULL pointer is returned but */
/* must be exchanged by a dummy non NULL pointer because this */
/* function reports errors by NULL pointers */
if (data == 0)
return (Patterns) &dummy_data;
return (Patterns) data;
break;
default:
KernelErrorCode = KRERR_PARAMETERS;
return (Patterns) NULL;
}
}
/*****************************************************************************
FUNCTION : kr_SizeOfInputSubPat
PURPOSE : For the current pattern set and the specified sub pattern size,
the size of the input part of the first sub pattern of the first pattern is
returned. Negative return values indicate KernelErrorCode. Size 0 is a valid
return value since the pattern may contain no data.
RETURNS : negative Kernel Error Codes or positive valid value
NOTES :
UPDATE :
******************************************************************************/
int kr_SizeOfInputSubPat(void)
{
krui_err err;
if (np_sub_pat_sizes_valid)
return np_sub_pat_input_size;
err = kr_np_GetSubPatSizes(&np_sub_pat_input_size,
&np_sub_pat_output_size);
if (err == KRERR_NO_ERROR)
{
np_sub_pat_sizes_valid = TRUE;
return np_sub_pat_input_size;
}
return err;
}
/*****************************************************************************
FUNCTION : kr_SizeOfOutputSubPat
PURPOSE : For the current pattern set and the specified sub pattern size,
the size of the output part of the first sub pattern of the first pattern is
returned. Negative return values indicate KernelErrorCode. Size 0 is a valid
return value since the pattern may contain no data.
RETURNS : negative Kernel Error Codes or positive valid value
NOTES :
UPDATE :
******************************************************************************/
int kr_SizeOfOutputSubPat(void)
{
krui_err err;
if (np_sub_pat_sizes_valid)
return np_sub_pat_output_size;
err = kr_np_GetSubPatSizes(&np_sub_pat_input_size,
&np_sub_pat_output_size);
if (err == KRERR_NO_ERROR)
{
np_sub_pat_sizes_valid = TRUE;
return np_sub_pat_output_size;
}
return err;
}
/*****************************************************************************
FUNCTIONS WHICH ARE CALLED BY THE PATTERN PARSER OR FROM INSIDE THIS
MODULE. DON'T USE THESE FUNCTIONS FOR OTHER PURPOSES !!!!!
******************************************************************************/
/*****************************************************************************
FUNCTION : kr_np_AllocatePatternSet
PURPOSE : looks for a free slot in pattern set array and allocates <number>
of free pattern descriptors
RETURNS : kernel error code
NOTES : don't call this function. This function is only to be
called by the parser or by functions inside this module
UPDATE :
******************************************************************************/
krui_err kr_np_AllocatePatternSet(int *pat_set, int number)
{
krui_err err_code;
int i;
int set = -1;
if (np_used_pat_set_entries == 0)
{
/* never patterns allocated */
err_code = kr_np_InitPattern();
if (err_code != KRERR_NO_ERROR)
return err_code;
}
/* check for free pattern set entry */
for (i=0; i<np_used_pat_set_entries; i++)
{
if (!np_pat_set_used[i])
{
set = i;
break;
}
}
if (set == -1)
{
/* no more free entries */
return KRERR_NP_NO_MORE_ENTRIES;
}
/* allocate array of pattern descriptors */
np_pat_sets[set] =
(pattern_descriptor *) malloc(number * sizeof(pattern_descriptor));
if (np_pat_sets[set] == (pattern_descriptor *) NULL && number != 0)
return KRERR_INSUFFICIENT_MEM;
/* initialize part of the pattern descriptors */
for (i=0; i<number; i++)
{
np_pat_sets[set][i].input_fixsize = 0;
np_pat_sets[set][i].output_fixsize = 0;
np_pat_sets[set][i].input_pattern = (float *) NULL;
np_pat_sets[set][i].output_pattern = (float *) NULL;
np_pat_sets[set][i].input_info = (char *) NULL;
np_pat_sets[set][i].output_info = (char *) NULL;
}
/* store number of allocated descriptors */
np_info[set].number_of_pattern = number;
np_info_valid[set] = FALSE; /* only number_of_pattern is valid */
/* sucessfull return */
np_pat_set_used[set] = TRUE;
*pat_set = set;
return KRERR_NO_ERROR;
}
/*****************************************************************************
FUNCTION : kr_np_AllocatePattern
PURPOSE : uses the information provided in given pattern descriptor to
allocate memory for pattern data
RETURNS : kernel error code
NOTES : don't call this function. This function is only to be
called by the parser or by functions inside this module
UPDATE :
******************************************************************************/
krui_err kr_np_AllocatePattern(pattern_descriptor *pattern,
bool input)
{
int i;
int size;
if (np_used_pat_set_entries == 0)
return KRERR_NO_PATTERNS;
if (input)
{
size = pattern -> input_fixsize;
for (i=0; i<pattern -> input_dim; i++)
size *= (pattern -> input_dim_sizes)[i];
pattern -> input_info = (char *) NULL;
pattern -> input_pattern = (float *) malloc(size * sizeof(float));
if (pattern -> input_pattern == (float *) NULL && size != 0)
return KRERR_INSUFFICIENT_MEM;
else
return KRERR_NO_ERROR;
}
else
{
size = pattern -> output_fixsize;
for (i=0; i<pattern -> output_dim; i++)
size *= (pattern -> output_dim_sizes)[i];
pattern -> output_info = (char *) NULL;
pattern -> output_pattern = (float *) malloc(size * sizeof(float));
if (pattern -> output_pattern == (float *) NULL && size != 0)
return KRERR_INSUFFICIENT_MEM;
else
return KRERR_NO_ERROR;
}
}
/*****************************************************************************
FUNCTION : kr_np_GetDescriptor
PURPOSE : determine a pointer to a specified pattern descriptor
and make this pattern to be the current pattern
RETURNS : kernel error code
NOTES : don't call this function. This function is only to be
called by the parser or by functions inside this module
UPDATE :
******************************************************************************/
krui_err kr_np_GetDescriptor(int pat_set, int number,
pattern_descriptor **pattern)
{
if (np_used_pat_set_entries == 0)
return KRERR_NO_PATTERNS;
if (pat_set < 0 || pat_set >= np_used_pat_set_entries ||
!np_pat_set_used[pat_set])
return KRERR_NP_NO_SUCH_PATTERN_SET;
if (number >= np_info[pat_set].number_of_pattern)
return KRERR_PATTERN_NO;
*pattern = np_current_pattern = &(np_pat_sets[pat_set][number]);
return KRERR_NO_ERROR;
}
/*****************************************************************************
INTERNAL FUNCTIONS OF THIS MODULE. IMPOSSIBLE TO CALL THESE FUNCTIONS
FROM OUTSIDE THE MODULE (IF NOBODY CHANGES THE STATIC DECLARATION) !!!!!!!
******************************************************************************/
/*****************************************************************************
FUNCTION : kr_np_InitPattern
PURPOSE : initialization of pattern descriptor array
RETURNS : kernel error code
NOTES : internal use only
UPDATE :
******************************************************************************/
static krui_err kr_np_InitPattern(void)
{
int i;
np_pat_sets = (pattern_descriptor **) malloc(NO_OF_PAT_SETS *
sizeof(pattern_descriptor *));
np_pat_set_used = (bool *) malloc(NO_OF_PAT_SETS * sizeof(bool));
np_info = (pattern_set_info *) malloc(NO_OF_PAT_SETS *
sizeof(pattern_set_info));
np_info_valid = (bool *) malloc(NO_OF_PAT_SETS * sizeof(bool));
if (np_pat_sets == (pattern_descriptor **) NULL ||
np_info == (pattern_set_info *) NULL ||
np_info_valid == (bool *) NULL)
{
return KRERR_INSUFFICIENT_MEM;
}
else
{
np_used_pat_set_entries = NO_OF_PAT_SETS;
for (i=0; i<NO_OF_PAT_SETS; i++)
{
np_pat_sets[i] = (pattern_descriptor *) NULL;
np_pat_set_used[i] = FALSE;
np_info_valid[i] = FALSE;
}
return KRERR_NO_ERROR;
}
}
/*****************************************************************************
FUNCTION : kr_np_ReallocatePatternSet
PURPOSE : reallocates the pattern set <pat_set> to contain <new_number>
of pattern entries.
RETURNS : kernel error code
NOTES : internal use only
UPDATE :
******************************************************************************/
static krui_err kr_np_ReallocatePatternSet(int pat_set, int new_number)
{
pattern_descriptor *new_mem;
/* check whether patterns are allocated */
if (np_used_pat_set_entries == 0)
return KRERR_NP_NO_SUCH_PATTERN_SET;
/* check whether the pattern set is present */
if (!np_pat_set_used[pat_set])
return KRERR_NP_NO_SUCH_PATTERN_SET;
/* reallocate array of pattern descriptors */
if (np_pat_sets[pat_set] != (pattern_descriptor *) NULL)
{
new_mem = (pattern_descriptor *)
realloc(np_pat_sets[pat_set],
new_number * sizeof(pattern_descriptor));
}
else
{
new_mem = (pattern_descriptor *)
malloc(new_number * sizeof(pattern_descriptor));
}
if (new_mem == (pattern_descriptor *) NULL && new_number != 0)
return KRERR_INSUFFICIENT_MEM;
np_pat_sets[pat_set] = new_mem;
/* store number of allocated descriptors */
np_info[pat_set].number_of_pattern = new_number;
np_info_valid[pat_set] = FALSE; /* only number_of_pattern is valid */
/* sucessfull return */
return KRERR_NO_ERROR;
}
/*****************************************************************************
FUNCTION : kr_np_DeletePatternSet
PURPOSE : delete a pattern set and free all memory
RETURNS : kernel error code
NOTES : internal use only
UPDATE :
******************************************************************************/
static krui_err kr_np_DeletePatternSet(int pat_set)
{
int i;
pattern_descriptor *p;
/* check for valid number of pattern set */
if (np_used_pat_set_entries == 0)
return KRERR_NO_PATTERNS;
if (pat_set<0 || pat_set>=np_used_pat_set_entries)
return KRERR_NP_NO_SUCH_PATTERN_SET;
p = np_pat_sets[pat_set];
if (!np_pat_set_used[pat_set])
return KRERR_NP_NO_SUCH_PATTERN_SET;
/* free all pattern */
for (i=0; i<np_info[pat_set].number_of_pattern; i++)
{
if (p -> input_pattern != (float *) NULL)
free(p -> input_pattern);
if (p -> input_info != (char *) NULL)
free(p -> input_info);
if (p -> output_pattern != (float *) NULL)
free(p -> output_pattern);
if (p -> output_info != (char *) NULL)
free(p -> output_info);
p++;
}
/* free the pattern descriptors */
if (np_pat_sets[pat_set] != (pattern_descriptor *) NULL)
free(np_pat_sets[pat_set]);
np_pat_sets[pat_set] = (pattern_descriptor *) NULL;
np_pat_set_used[pat_set] = FALSE;
np_info[pat_set].number_of_pattern = 0;
np_info_valid[pat_set] = FALSE;
np_current_pattern = (pattern_descriptor *) NULL;
return KRERR_NO_ERROR;
}
/*****************************************************************************
FUNCTION : kr_np_DeletePattern
PURPOSE : delete a specific pattern form a pattern set
RETURNS : kernel error code
NOTES : internal use only
UPDATE :
******************************************************************************/
static krui_err kr_np_DeletePattern(int pat_set, int pattern)
{
pattern_descriptor *p;
int i;
/* check for valid number of pattern set */
if (np_used_pat_set_entries == 0)
return KRERR_NO_PATTERNS;
if (pat_set<0 || pat_set>=np_used_pat_set_entries)
return KRERR_NP_NO_SUCH_PATTERN_SET;
p = np_pat_sets[pat_set];
if (!np_pat_set_used[pat_set])
return KRERR_NP_NO_SUCH_PATTERN_SET;
if (pattern < 0 || pattern >= np_info[pat_set].number_of_pattern)
return KRERR_NP_NO_SUCH_PATTERN;
/* free memory for the specified pattern */
p += pattern;
if (p -> input_pattern != (float *) NULL)
free(p -> input_pattern);
if (p -> input_info != (char *) NULL)
free(p -> input_info);
if (p -> output_pattern != (float *) NULL)
free(p -> output_pattern);
if (p -> output_info != (char *) NULL)
free(p -> output_info);
/* move tail of array one position to fill up the empty entry */
for (i=pattern+1; i<np_info[pat_set].number_of_pattern; i++)
{
(void) memcpy((char *) p, (char *) (p+1), sizeof(pattern_descriptor));
p++;
}
/* last entry of the array is no longer active */
return kr_np_ReallocatePatternSet(pat_set,
np_info[pat_set].number_of_pattern-1);
}
/*****************************************************************************
FUNCTION : kr_np_AddPattern
PURPOSE : Add an empty pattern descriptor to the specified pattern set.
The position of the pattern inside the set is returned
in <pattern>.
RETURNS : kernel error code
NOTES : internal use only
UPDATE :
******************************************************************************/
static krui_err kr_np_AddPattern(int pat_set, int *pattern)
{
krui_err err;
pattern_descriptor *p;
int number;
/* check for valid number of pattern set */
if (np_used_pat_set_entries == 0)
return KRERR_NO_PATTERNS;
if (pat_set<0 || pat_set>=np_used_pat_set_entries)
return KRERR_NP_NO_SUCH_PATTERN_SET;
p = np_pat_sets[pat_set];
if (!np_pat_set_used[pat_set])
return KRERR_NP_NO_SUCH_PATTERN_SET;
number = np_info[pat_set].number_of_pattern + 1;
err = kr_np_ReallocatePatternSet(pat_set, number);
if (err != KRERR_NO_ERROR)
return err;
p = np_pat_sets[pat_set];
p += (number-1);
/* initialize part of the new pattern descriptors */
{
p -> input_fixsize = 0;
p -> output_fixsize = 0;
p -> input_dim = 0;
p -> output_dim = 0;
p -> input_pattern = (float *) NULL;
p -> output_pattern = (float *) NULL;
}
*pattern = (number-1);
return KRERR_NO_ERROR;
}
/*****************************************************************************
FUNCTION : kr_np_LoadPatternFile
PURPOSE : loads new or old pattern file from pat_file. The number of the
associated pattern set is returned in pat_set.
RETURNS : kernel error code
NOTES : internal use only
UPDATE :
******************************************************************************/
static krui_err kr_np_LoadPatternFile(FILE *pat_file, int *pat_set)
{
int i;
bool free;
krui_err err_code;
int pattern_set;
/* be sure to have a place where to put the patterns */
if (np_used_pat_set_entries == 0)
{
/* never patterns allocated */
err_code = kr_np_InitPattern();
if (err_code != KRERR_NO_ERROR)
return err_code;
}
else
{
free = FALSE;
/* check for free entry before starting parser */
for (i=0; i<np_used_pat_set_entries; i++)
{
if (!np_pat_set_used[i])
{
free = TRUE;
break;
}
}
if (!free)
return KRERR_NP_NO_MORE_ENTRIES;
}
/* reset the scanner and the parser */
scanner_init_scanner(pat_file);
/* parse pattern file and check for errors */
if (parse_pattern_file(&pattern_set) != 0)
{
(void) kr_np_DeletePatternSet(pattern_set);
return KRERR_FILE_FORMAT;
}
else
{
*pat_set = pattern_set;
return KRERR_NO_ERROR;
}
}
/*****************************************************************************
FUNCTION : kr_np_SavePatternFile
PURPOSE : save the pattern set pat_set to out_file
RETURNS : kernel error code
NOTES : internal use only
UPDATE :
******************************************************************************/
static krui_err kr_np_SavePatternFile(FILE *out_file, int pat_set)
{
pattern_set_info info;
krui_err err_code;
int i, j, n;
float *in_pat, *out_pat;
time_t clock;
if (np_used_pat_set_entries == 0)
return KRERR_NO_PATTERNS;
if (pat_set<0 || pat_set>=np_used_pat_set_entries)
return KRERR_NP_NO_SUCH_PATTERN_SET;
if (!np_pat_set_used[pat_set])
return KRERR_NP_NO_SUCH_PATTERN_SET;
err_code = kr_np_GetInfo(pat_set, &info);
if (err_code != KRERR_NO_ERROR)
return err_code;
if (info.number_of_pattern == 0)
return KRERR_NO_PATTERNS;
fprintf(out_file, "SNNS pattern definition file V%d.%d\n",
CURRENT_VERSION_V, CURRENT_VERSION_R);
clock = time((time_t *) NULL);
fprintf(out_file, "generated at %s\n\n", (char *) ctime(&clock));
fprintf(out_file, "No. of patterns : %d\n", info.number_of_pattern);
fprintf(out_file, "No. of input units : %d\n", info.in_fixsize);
if (info.out_fixsize != 0)
fprintf(out_file, "No. of output units : %d\n", info.out_fixsize);
if (info.in_number_of_dims != 0)
{
fprintf(out_file, "No. of variable input dimensions : %d\n",
info.in_number_of_dims);
fprintf(out_file, "Maximum input dimensions : [ ");
for (i=0; i<info.in_number_of_dims; i++)
{
fprintf(out_file, "%d ", info.in_max_dim_sizes[i]);
}
fprintf(out_file, "]\n");
}
if (info.out_fixsize != 0 && info.out_number_of_dims != 0)
{
fprintf(out_file, "No. of variable output dimensions : %d\n",
info.out_number_of_dims);
fprintf(out_file, "Maximum output dimensions : [ ");
for (i=0; i<info.out_number_of_dims; i++)
{
fprintf(out_file, "%d ", info.out_max_dim_sizes[i]);
}
fprintf(out_file, "]\n");
}
fprintf(out_file, "\n");
for (j=0; j<info.number_of_pattern; j++)
{
if (np_pat_sets[pat_set][j].input_fixsize > 0)
{
fprintf(out_file, "# Input pattern %d:\n", j+1);
n = info.in_fixsize;
if (info.in_number_of_dims != 0)
{
fprintf(out_file, "[ ");
for (i=0; i<np_pat_sets[pat_set][j].input_dim; i++)
{
fprintf(out_file, "%d ",
np_pat_sets[pat_set][j].input_dim_sizes[i]);
n *= np_pat_sets[pat_set][j].input_dim_sizes[i];
}
fprintf(out_file, "]\n");
}
in_pat = np_pat_sets[pat_set][j].input_pattern;
for (i=0; i<n; i++)
{
fprintf(out_file, "%g ", *in_pat++);
if (i == n - 1 || i%10 == 9)
fprintf(out_file, "\n");
}
}
if (np_pat_sets[pat_set][j].output_fixsize > 0)
{
fprintf(out_file, "# Output pattern %d:\n", j+1);
n = info.out_fixsize;
if (info.out_number_of_dims != 0)
{
fprintf(out_file, "[ ");
for (i=0; i<np_pat_sets[pat_set][j].output_dim; i++)
{
fprintf(out_file, "%d ",
np_pat_sets[pat_set][j].output_dim_sizes[i]);
n *= np_pat_sets[pat_set][j].output_dim_sizes[i];
}
fprintf(out_file, "]\n");
}
out_pat = np_pat_sets[pat_set][j].output_pattern;
for (i=0; i<n; i++)
{
fprintf(out_file, "%g ", *out_pat++);
if (i == n - 1 || i%10 == 9)
fprintf(out_file, "\n");
}
}
}
return KRERR_NO_ERROR;
}
/*****************************************************************************
FUNCTION : kr_np_GetInfo
PURPOSE : get some information about the specified pattern set
RETURNS : kernel error code
NOTES : internal use only
UPDATE :
******************************************************************************/
static krui_err kr_np_GetInfo(int pat_set, pattern_set_info *info)
{
int i, j;
pattern_descriptor *p;
if (np_used_pat_set_entries == 0)
return KRERR_NO_PATTERNS;
if (pat_set < 0 || pat_set >= np_used_pat_set_entries ||
!np_pat_set_used[pat_set])
return KRERR_NP_NO_SUCH_PATTERN_SET;
if (np_info_valid[pat_set])
{
*info = np_info[pat_set];
return KRERR_NO_ERROR;
}
p = np_pat_sets[pat_set];
info -> number_of_pattern = np_info[pat_set].number_of_pattern;
info -> fixed_fixsizes = TRUE;
if (info -> number_of_pattern > 0 && p != (pattern_descriptor *) NULL)
{
info -> output_present = p-> output_fixsize != 0;
info -> in_fixsize = p -> input_fixsize;
info -> out_fixsize = p-> output_fixsize;
info -> in_number_of_dims = p->input_dim;
info -> out_number_of_dims = p->output_dim;
for (j=0; j < p->input_dim; j++)
{
(info -> in_max_dim_sizes)[j] = (info -> in_min_dim_sizes)[j] =
(p -> input_dim_sizes)[j];
}
for (j=0; j < p->output_dim; j++)
{
(info -> out_max_dim_sizes)[j] = (info -> out_min_dim_sizes)[j] =
(p -> output_dim_sizes)[j];
}
}
for (i=0; i<info -> number_of_pattern; i++)
{
if (p -> input_fixsize != info -> in_fixsize)
{
info -> fixed_fixsizes = FALSE;
info -> in_fixsize = -1;
}
if (p -> output_fixsize != info -> out_fixsize)
{
info -> fixed_fixsizes = FALSE;
info -> out_fixsize = -1;
}
for (j=0; j < p->input_dim; j++)
{
if ((p -> input_dim_sizes)[j] > (info -> in_max_dim_sizes)[j])
(info -> in_max_dim_sizes)[j] = p -> input_dim_sizes[j];
if ((p -> input_dim_sizes)[j] < (info -> in_min_dim_sizes)[j])
(info -> in_min_dim_sizes)[j] = p -> input_dim_sizes[j];
}
for (j=0; j < p->output_dim; j++)
{
if ((p -> output_dim_sizes)[j] > (info -> out_max_dim_sizes)[j])
(info -> out_max_dim_sizes)[j] = p -> output_dim_sizes[j];
if ((p -> output_dim_sizes)[j] < (info -> out_min_dim_sizes)[j])
(info -> out_min_dim_sizes)[j] = p -> output_dim_sizes[j];
}
p++;
}
np_info[pat_set] = *info;
np_info_valid[pat_set] = TRUE;
return KRERR_NO_ERROR;
}
/*****************************************************************************
FUNCTION : kr_np_GetSubPatSizes
PURPOSE : Depending on the current pattern set and the sub pattern
training scheme, which must be defined, the size of the first input sub
pattern and the size of the first output sub pattern is computed.
RETURNS : kernel error code
NOTES : internal use only
UPDATE :
******************************************************************************/
static krui_err kr_np_GetSubPatSizes(int *input_size, int *output_size)
{
int pat_set;
pattern_descriptor *pattern;
int i;
if (!npui_train_defined)
return KRERR_NP_NO_TRAIN_SCHEME;
pat_set = npui_pat_sets[npui_curr_pat_set];
pattern = &(np_pat_sets[pat_set][0]);
*input_size = pattern -> input_fixsize;
for (i=0; i<pattern -> input_dim; i++)
{
*input_size *= np_t_insize[i];
}
*output_size = pattern -> output_fixsize;
for (i=0; i<pattern -> output_dim; i++)
{
*output_size *= np_t_outsize[i];
}
return KRERR_NO_ERROR;
}
/*****************************************************************************
FUNCTION : kr_np_GetSubPat
PURPOSE : copy a sub pattern into another area
A sub pattern is cut out of the current pattern at position
<pos_coord> with size <size_coord>. According to <input> the input
part or the output part of the current pattern is used. A pointer to
an array of float which contains the cut part is returned in <data>.
<pos_coord> is an array of int which defines the position of the sub
pattern inside the variable sized dimensions of the pattern.
<size_coord> is an array of int which defines the size of the sub
pattern in each dimensional direction. Both arrays must contain
<input_dim> (or <output_dim>) entries (see pattern descriptor).
Example: pattern with input_fixsize 2, input_dim 2, input_dim_sizes [4 5]
(hint: the values of the pattern represent the position)
{
0.00, 0.01, 0.10, 0.11, 0.20, 0.21, 0.30, 0.31, 0.40, 0.41,
1.00, 1.01, 1.10, 1.11, 1.20, 1.21, 1.30, 1.31, 1.40, 1.41,
2.00, 2.01, 2.10, 2.11, 2.20, 2.21, 2.30, 2.31, 2.40, 2.41,
3.00, 3.01, 3.10, 3.11, 3.20, 3.21, 3.30, 3.31, 3.40, 3.41,
}
the sub pattern with <pos_coord> [1 2], <size_coord> [3 2] looks like
this:
{
1.20, 1.21, 1.30, 1.31,
2.20, 2.21, 2.30, 2.31,
3.20, 3.21, 3.30, 3.31,
}
The parameter entries returns the number of entries in the data field.
RETURNS : kernel error code
NOTES : internal use only
UPDATE :
******************************************************************************/
static krui_err kr_np_GetSubPat(bool input, int *pos_coord, int *size_coord,
float **data, int *entries)
{
int u_dim; /* copy of all necessary variables from */
int u_size; /* pattern descriptor, depending on */
int *u_dim_sizes; /* <input> */
float *u_pattern;
int npu_subpatsize;
float *npu_subpat;
int f_size; /* size of copy area */
int i;
int c[MAX_NO_OF_VAR_DIM]; /* counter for the dimensions */
int copy_size; /* size of copy block for each memcpy */
float *cf; /* pointer into pattern (copy source) */
float *cdest; /* copy destination */
bool stop; /* TRUE if all done */
int offset; /* offset in multidimensional array */
/* check for valid pattern */
if (np_used_pat_set_entries == 0)
return KRERR_NO_PATTERNS;
if (np_current_pattern == (pattern_descriptor *) NULL)
return KRERR_NP_NO_CURRENT_PATTERN;
/* make a copy of all pattern info to work with */
if (input)
{
u_dim = np_current_pattern -> input_dim;
u_size = np_current_pattern -> input_fixsize;
u_dim_sizes = np_current_pattern -> input_dim_sizes;
u_pattern = np_current_pattern -> input_pattern;
npu_subpatsize = np_i_subpatsize;
npu_subpat = np_i_subpat;
}
else
{
u_dim = np_current_pattern -> output_dim;
u_size = np_current_pattern -> output_fixsize;
u_dim_sizes = np_current_pattern -> output_dim_sizes;
u_pattern = np_current_pattern -> output_pattern;
npu_subpatsize = np_o_subpatsize;
npu_subpat = np_o_subpat;
}
/* check whether this pattern exists */
if (u_size == 0)
{
if (input)
return KRERR_NP_NO_SUCH_PATTERN;
else
{
/* this may be a network without output neurons, so don't */
/* produce an error but set the data pointer to NULL */
*data = (float *) NULL;
if (entries != (int *) NULL)
*entries = 0;
return KRERR_NO_ERROR;
}
}
/* calculate size of the sub pattern and check dimensions */
f_size = u_size;
for (i=0; i<u_dim; i++)
{
f_size *= size_coord[i];
if (pos_coord[i] + size_coord[i] > u_dim_sizes[i])
return KRERR_NP_DIMENSION;
c[i] = 0;
}
/* allocate space for sub pattern if necessary */
if (f_size > npu_subpatsize)
{
if (npu_subpat != (float *) NULL)
free(npu_subpat);
npu_subpat = (float *) malloc(f_size * sizeof(float));
if (npu_subpat == (float *) NULL && f_size != 0)
{
return KRERR_INSUFFICIENT_MEM;
}
npu_subpatsize = f_size;
/* copy back new address and size */
if (input)
{
np_i_subpatsize = npu_subpatsize;
np_i_subpat = npu_subpat;
}
else
{
np_o_subpatsize = npu_subpatsize;
np_o_subpat = npu_subpat;
}
}
/* calculate size of one copy block. this includes the size of the */
/* dimension with highest index (least significant dimension) */
copy_size = u_size;
if (u_dim>0)
copy_size *= size_coord[u_dim-1];
/* copy the sub pattern */
cdest = npu_subpat;
do
{
/* calculate offset in source pattern */
offset = 0;
for (i=0; i<u_dim; i++)
{
offset *= u_dim_sizes[i];
offset += pos_coord[i] + c[i];
}
offset *= u_size;
cf = u_pattern + offset;
/* copy part of the pattern. this inlcudes the least significant */
/* dimension */
(void) memcpy((char *) cdest, (char *) cf, copy_size * sizeof(float));
cdest += copy_size;
/* count the dimensions and check whether we have to go on. */
/* the least significant dimension is omitted, because it is already */
/* copied */
stop = TRUE;
for (i=u_dim-2; i>=0; i--)
{
c[i]++;
if (c[i] == size_coord[i])
c[i] = 0;
else
{
stop = FALSE;
break;
}
}
} while (!stop);
/* all done, return results */
*data = npu_subpat;
if (entries != (int *) NULL)
*entries = f_size;
return KRERR_NO_ERROR;
}
/*****************************************************************************
FUNCTION : kr_np_SetSubPat
PURPOSE : copy another area into a sub pattern
A sub pattern is cut out of the current pattern at position
<pos_coord> with size <size_coord>. According to <input> the input
part or the output part of the current pattern is used.
<pos_coord> is an array of int which defines the position of the sub
pattern inside the variable sized dimensions of the pattern.
<size_coord> is an array of int which defines the size of the sub
pattern in each dimensional direction. Both arrays must contain
<input_dim> (or <output_dim>) entries (see pattern descriptor).
Example: pattern with input_fixsize 2, input_dim 2, input_dim_sizes [4 5]
(hint: the values of the pattern represent the position)
{
0.00, 0.01, 0.10, 0.11, 0.20, 0.21, 0.30, 0.31, 0.40, 0.41,
1.00, 1.01, 1.10, 1.11, 1.20, 1.21, 1.30, 1.31, 1.40, 1.41,
2.00, 2.01, 2.10, 2.11, 2.20, 2.21, 2.30, 2.31, 2.40, 2.41,
3.00, 3.01, 3.10, 3.11, 3.20, 3.21, 3.30, 3.31, 3.40, 3.41,
}
the sub pattern with <pos_coord> [1 2], <size_coord> [3 2] looks like
this:
{
1.20, 1.21, 1.30, 1.31,
2.20, 2.21, 2.30, 2.31,
3.20, 3.21, 3.30, 3.31,
}
The parameter entries returns the number of entries in the data field.
RETURNS : kernel error code
NOTES : internal use only
UPDATE :
******************************************************************************/
static krui_err kr_np_SetSubPat(bool input, int *pos_coord, int *size_coord,
float *data, int entries)
{
int u_dim; /* copy of all necessary variables from */
int u_size; /* pattern descriptor, depending on */
int *u_dim_sizes; /* <input> */
float *u_pattern;
int f_size; /* size of copy area */
int i;
int c[MAX_NO_OF_VAR_DIM]; /* counter for the dimensions */
int copy_size; /* size of copy block for each memcpy */
float *cf; /* pointer into pattern (copy destination) */
float *csource; /* copy source */
bool stop; /* TRUE if all done */
int offset; /* offset in multidimensional array */
/* check for valid pattern */
if (np_used_pat_set_entries == 0)
return KRERR_NO_PATTERNS;
if (np_current_pattern == (pattern_descriptor *) NULL)
return KRERR_NP_NO_CURRENT_PATTERN;
/* make a copy of all pattern info to work with */
if (input)
{
u_dim = np_current_pattern -> input_dim;
u_size = np_current_pattern -> input_fixsize;
u_dim_sizes = np_current_pattern -> input_dim_sizes;
u_pattern = np_current_pattern -> input_pattern;
}
else
{
u_dim = np_current_pattern -> output_dim;
u_size = np_current_pattern -> output_fixsize;
u_dim_sizes = np_current_pattern -> output_dim_sizes;
u_pattern = np_current_pattern -> output_pattern;
}
/* check whether this pattern exists or whether all is done */
if (u_size == 0)
{
if (entries == 0)
return KRERR_NO_ERROR;
else
return KRERR_NP_NO_SUCH_PATTERN;
}
/* calculate size of the sub pattern and check dimensions */
f_size = u_size;
for (i=0; i<u_dim; i++)
{
f_size *= size_coord[i];
if (pos_coord[i] + size_coord[i] > u_dim_sizes[i])
return KRERR_NP_DIMENSION;
c[i] = 0;
}
/* check whether calculated space fits the delievered data block */
if (f_size != entries)
return KRERR_NP_DOES_NOT_FIT;
/* calculate size of one copy block. this includes the size of the */
/* dimension with highest index (least significant dimension) */
copy_size = u_size;
if (u_dim>0)
copy_size *= size_coord[u_dim-1];
/* copy the sub pattern */
csource = data;
do
{
/* calculate offset in destination pattern */
offset = 0;
for (i=0; i<u_dim; i++)
{
offset *= u_dim_sizes[i];
offset += pos_coord[i] + c[i];
}
offset *= u_size;
cf = u_pattern + offset;
/* copy part of the pattern. this inlcudes the least significant */
/* dimension */
(void) memcpy((char *) cf, (char *)csource, copy_size * sizeof(float));
csource += copy_size;
/* count the dimensions and check whether we have to go on. */
/* the least significant dimension is omitted, because it is already */
/* copied */
stop = TRUE;
for (i=u_dim-2; i>=0; i--)
{
c[i]++;
if (c[i] == size_coord[i])
c[i] = 0;
else
{
stop = FALSE;
break;
}
}
} while (!stop);
/* all done, return results */
return KRERR_NO_ERROR;
}
/*****************************************************************************
FUNCTION : kr_np_align_sub_pos
PURPOSE : For a given pattern dimension size <psize> of <dim>
dimensions and a given sub pattern size <ssize> the position
<spos> of the sub pattern is alligned to a valid position
and the ordering number of this sub pattern is returned
in <n>. The shift pattern given in <sstep> is used to
find valid allignment positions
RETURNS : TRUE if succesfull, FALSE if inconsistent parameters
<n> starts with 0 and ends with <number of possible
positions> - 1
<spos> gives the new aligned position
NOTES : internal function
UPDATE :
******************************************************************************/
static bool kr_np_align_sub_pos(int dim, int *n, int *psize, int *ssize,
int *sstep, int *spos)
{
int ns[MAX_NO_OF_VAR_DIM];
register int i;
register int ts = 0;
for (i=0; i<dim; i++)
{
/* calculate how much steps could be made in each dimension */
ns[i] = (psize[i] - ssize[i] + sstep[i]) / sstep[i];
if (ns[i] == 0)
return FALSE;
/* align the position of this dimension */
spos[i] -= spos[i] % sstep[i];
if (spos[i]+ssize[i] >= psize[i]+1)
spos[i] = 0;
/* add the position of this dimension to the absolute position */
ts *= ns[i];
ts += spos[i]/sstep[i];
}
*n = ts;
return TRUE;
}
/*****************************************************************************
FUNCTION : kr_np_gen_sub_pos
PURPOSE : For a given pattern dimension size <psize> of <dim>
dimensions and a given sub pattern size <ssize> the position
<spos> of the <n>th sub pattern is calculated. The shift
pattern given in <sstep> is used to move sub pattern over
the pattern.
If <count> is TRUE, only the number of possible positions
is determined and returned in <n> if at least 1 valid
position exists. <spos> is of no effect and may be NULL.
RETURNS : TRUE if the <n>th subpattern exists or if <count> is TRUE
and at least 1 valid position exists, FALSE if <n> < 0.
If <n> is higher than the available number of subpattern, a
wraparound occurs.
<n> starts with 0 and ends with <number of possible
positions> - 1 or returns number of possible positions.
NOTES : internal function
UPDATE :
******************************************************************************/
static bool kr_np_gen_sub_pos(int dim, int *n, int *psize, int *ssize,
int *sstep, int *spos, bool count)
{
int ns[MAX_NO_OF_VAR_DIM];
int i;
int ts;
int nn;
nn = *n;
/* calculate how much steps could be made in each dimension */
/* and the total number of positions ts (define the bases of a */
/* multi base numerative system and determine the highest */
/* representable number) */
ts = 1;
for (i=dim-1; i>=0; i--)
{
ns[i] = (psize[i] - ssize[i] + sstep[i]) / sstep[i];
if (ns[i] == 0)
return FALSE;
ts *= ns[i];
}
/* check whether this is all what we want to do now */
if (count)
{
*n = ts;
return TRUE;
}
/* check range of requested step position */
if (nn<0)
return FALSE;
/* if requested position is higher than available positions, perform */
/* wraparaound (this is usefull/necessary for pattern without subpattern */
nn = nn%ts;
/* calculate step position of the <n>th sub pattern (like counting */
/* in a multi base numerative system) */
for (i=dim-1; i>=0; i--)
{
spos[i] = (nn % ns[i]) * sstep[i];
nn /= ns[i];
}
return TRUE;
}
/*****************************************************************************
FUNCTION : kr_np_allocate_pat_train_entries
PURPOSE : allocate or reallocate an array which will later include
the sorted or shuffled pattern order (during training)
RETURNS : FALSE if malloc fails
NOTES : internal use only
UPDATE :
******************************************************************************/
static bool kr_np_allocate_pat_train_entries(int n)
{
if (n > np_pat_train_size)
{
if (np_pat_train_order != (int *) NULL)
free(np_pat_train_order);
np_pat_train_size = 0;
np_pat_train_order = (int *) malloc(n * sizeof(int));
if (np_pat_train_order == (int *) NULL && n != 0)
return FALSE;
np_pat_train_size = n;
np_pat_train_valid = FALSE;
}
return TRUE;
}
/*****************************************************************************
FUNCTION : kr_np_allocate_sub_pat_train_entries
PURPOSE : allocate or reallocate an array which will later include
the sorted or shuffled order of the sub pattern of the
current pattern
RETURNS : FALSE if malloc fails
NOTES : internal use only
UPDATE :
******************************************************************************/
static bool kr_np_allocate_sub_pat_train_entries(int n)
{
if (n > np_sub_pat_train_size)
{
if (np_sub_pat_train_order != (int *) NULL)
free(np_sub_pat_train_order);
np_sub_pat_train_size = 0;
np_sub_pat_train_order = (int *) malloc(n * sizeof(int));
if (np_sub_pat_train_order == (int *) NULL && n != 0)
return FALSE;
np_sub_pat_train_size = n;
np_sub_pat_train_valid = FALSE;
}
return TRUE;
}
/*****************************************************************************
FUNCTION : kr_np_order_pat_entries
PURPOSE : Fills the allocated array for the pattern ordering with
increasing numbers if patterns are sorted or with a
random permutation if patterns are shuffled.
<start> and <end> define the first and last pattern
number to be used
RETURNS : nothing
NOTES : internal use only
UPDATE :
******************************************************************************/
static void kr_np_order_pat_entries(int start, int end)
{
static bool shuffle;
static int c_start;
static int c_end;
register int i;
register int *fp;
register int h;
register int s;
register int n;
if (!np_pat_train_valid || c_start != start || c_end != end
|| shuffle != npui_shuffle_pattern)
{
fp = np_pat_train_order;
for (i=start; i<=end; i++)
*fp++ = i;
np_pat_train_valid = TRUE;
np_pat_train_number = end - start + 1;
c_start = start;
c_end = end;
shuffle = npui_shuffle_pattern;
}
if (shuffle)
{
n = np_pat_train_number;
fp = np_pat_train_order;
for (i=0; i<n; i++)
{
s = lrand48() % (n-i);
h = *fp;
*fp++ = np_pat_train_order[s+i];
np_pat_train_order[s+i] = h;
}
}
}
/*****************************************************************************
FUNCTION : kr_np_order_sub_pat_entries
PURPOSE : Fills the allocated array for the sub pattern ordering with
increasing numbers if sub patterns are sorted or with a
random permutation if sub patterns are shuffled.
<start> and <end> define the first and last sub pattern
number to be used
RETURNS : nothing
NOTES : internal use only
UPDATE :
******************************************************************************/
static void kr_np_order_sub_pat_entries(int start, int end)
{
static bool shuffle;
static int c_start;
static int c_end;
register int i;
register int *fp;
register int h;
register int s;
register int n;
if (!np_sub_pat_train_valid || c_start != start || c_end != end
|| shuffle != npui_shuffle_sub_pattern)
{
fp = np_sub_pat_train_order;
for (i=start; i<=end; i++)
*fp++ = i;
np_sub_pat_train_valid = TRUE;
np_sub_pat_train_number = end - start + 1;
c_start = start;
c_end = end;
shuffle = npui_shuffle_sub_pattern;
}
if (shuffle)
{
n = np_sub_pat_train_number;
fp = np_sub_pat_train_order;
for (i=0; i<n; i++)
{
s = lrand48() % (n-i);
h = *fp;
*fp++ = np_sub_pat_train_order[s+i];
np_sub_pat_train_order[s+i] = h;
}
}
}
/*****************************************************************************
FUNCTION : kr_np_DefineSubPatternOrdering
PURPOSE : definition of generation of sub pattern during training
The shape and ordering of sub patterns for training and display is
defined. <pat_set> specifies the pattern set to use. The flag
<input> determines whether input or output sub patterns are to be
defined. The array size_coord spezifies the shape of the sub pattern
like in kr_np_GetSubPat. The array incr_coord specifies how sub
patterns are generated from the whole pattern by shifting the shape
over this pattern. Each value in this array gives an incremental
offset for one dimensional direction. The start position is at [0 0
0 ...]. New positions are generated by adding the rightmost value of
incr_coord to the old position. If an overflow in this dimension
occurs, this coordinate is reset to 0 and the next position to the
left is incremented (and so on ...). After all sub patterns of one
pattern are generated the next pattern is used. Depending on
npui_shuffle_pattern and npui_shuffle_sub_pattern shuffling is
activated.
RETURNS : kernel error code
NOTES : internal use only
UPDATE :
******************************************************************************/
static krui_err kr_np_DefineSubPatternOrdering(int pat_set, bool input,
int *size_coord,
int *incr_coord)
{
krui_err err_code;
pattern_descriptor *p;
if (np_used_pat_set_entries == 0)
return KRERR_NO_PATTERNS;
if (pat_set < 0 || pat_set >= np_used_pat_set_entries ||
!np_pat_set_used[pat_set])
return KRERR_NP_NO_SUCH_PATTERN_SET;
err_code = kr_np_GetDescriptor(pat_set, 0, &p);
if (err_code != KRERR_NO_ERROR)
return err_code;
if (input)
{
memcpy((char *) np_t_insize, (char *) size_coord,
p->input_dim * sizeof(int));
memcpy((char *) np_t_instep, (char *) incr_coord,
p->input_dim * sizeof(int));
}
else
{
memcpy((char *) np_t_outsize, (char *) size_coord,
p->input_dim * sizeof(int));
memcpy((char *) np_t_outstep, (char *) incr_coord,
p->input_dim * sizeof(int));
}
np_pat_train_valid = FALSE;
np_sub_pat_train_valid = FALSE;
return KRERR_NO_ERROR;
}
/*****************************************************************************
FUNCTION : kr_np_showPatternSTD
PURPOSE : According to the mode kr_np_showPatternSTD stores the current
Pattern/sub Pattern into the units activation (and/or output)
values.
The modes are:
- OUTPUT_NOTHING
store input pattern into input units activations
- OUTPUT_ACT
store input pattern into input units activations and
store output pattern into output units activations
- OUTPUT_OUT
store input pattern into input units activations,
store output pattern into output units activations and
update output units output
RETURNS : kernel error code
NOTES : See include file glob_typ.h for mode constants.
internal use only
UPDATE :
******************************************************************************/
static krui_err kr_np_showPatternSTD(int mode)
{
register struct Unit *unit_ptr;
float *in_pat, *out_pat;
pattern_descriptor *pattern;
int in_pat_size, out_pat_size;
/* make the pattern to become the current pattern */
if ((KernelErrorCode =
kr_np_GetDescriptor(npui_pat_sets[npui_curr_pat_set],
npui_curr_pattern-1, &pattern))
!= KRERR_NO_ERROR)
return KernelErrorCode;
/* calc. startaddress of patterns */
if ((KernelErrorCode =
kr_np_GetSubPat(TRUE, npui_inpos, npui_insize, &in_pat,
&in_pat_size))
!= KRERR_NO_ERROR)
return KernelErrorCode;
if ((KernelErrorCode =
kr_np_GetSubPat(FALSE, npui_outpos, npui_outsize, &out_pat,
&out_pat_size))
!= KRERR_NO_ERROR)
return KernelErrorCode;
/* calculate the units, ignore error code concerning old pattern format */
(void) kr_IOCheck();
KernelErrorCode = KRERR_NO_ERROR;
/* check whether pattern fits the network, do not complain about */
/* missing output pattern */
if (NoOfInputUnits != in_pat_size ||
(NoOfOutputUnits != out_pat_size && out_pat_size != 0))
return KernelErrorCode = KRERR_NP_DOES_NOT_FIT;
switch (mode)
{
case OUTPUT_NOTHING:
FOR_ALL_UNITS( unit_ptr )
if ( IS_INPUT_UNIT( unit_ptr ) && UNIT_IN_USE( unit_ptr ))
if (in_pat_size--)
unit_ptr->act = *in_pat++;
break;
case OUTPUT_ACT:
FOR_ALL_UNITS( unit_ptr )
if UNIT_IN_USE( unit_ptr )
{
if IS_INPUT_UNIT( unit_ptr )
unit_ptr->act = *in_pat++;
if (IS_OUTPUT_UNIT( unit_ptr ) && out_pat_size != 0)
unit_ptr->act = *out_pat++;
}
break;
case OUTPUT_OUT:
FOR_ALL_UNITS( unit_ptr )
if UNIT_IN_USE( unit_ptr )
{
if IS_INPUT_UNIT( unit_ptr )
unit_ptr->act = *in_pat++;
if (IS_OUTPUT_UNIT( unit_ptr ) && out_pat_size != 0)
{
unit_ptr->act = *out_pat++;
if (unit_ptr->out_func == NULL)
/* Identity Function */
unit_ptr->Out.output = unit_ptr->act;
else
unit_ptr->Out.output =
(*unit_ptr->out_func) (unit_ptr->act);
}
}
break;
default:
KernelErrorCode = KRERR_PARAMETERS;
}
return( KernelErrorCode );
}
/*****************************************************************************
FUNCTION : kr_np_modifyPattern
PURPOSE : The current activation of the input and output units is used to
modify the current sub pattern.
RETURNS : kernel error code
NOTES : internal use only
UPDATE :
******************************************************************************/
static krui_err kr_np_modifyPattern(void)
{
register struct Unit *unit_ptr;
float *in_pat, *out_pat;
float *ip, *op;
pattern_descriptor *pattern;
/* make the pattern to become the current pattern */
if ((KernelErrorCode =
kr_np_GetDescriptor(npui_pat_sets[npui_curr_pat_set],
npui_curr_pattern-1, &pattern))
!= KRERR_NO_ERROR)
return KernelErrorCode;
/* calculate the units, ignore error code concerning old pattern format */
(void) kr_IOCheck();
KernelErrorCode = KRERR_NO_ERROR;
/* allocate memory to hold the sub pattern */
in_pat = (float *) malloc(NoOfInputUnits * sizeof(float));
out_pat = (float *) malloc(NoOfOutputUnits * sizeof(float));
if ((in_pat == (float *) NULL && NoOfInputUnits != 0)
|| (out_pat == (float *) NULL && NoOfOutputUnits != 0))
return KRERR_INSUFFICIENT_MEM;
/* copy unit activations into sub pattern area */
ip = in_pat;
op = out_pat;
FOR_ALL_UNITS(unit_ptr)
if (UNIT_IN_USE(unit_ptr))
{
if (IS_INPUT_UNIT(unit_ptr))
*ip++ = unit_ptr->act;
if (IS_OUTPUT_UNIT(unit_ptr))
*op++ = unit_ptr->act;
}
KernelErrorCode = KRERR_NO_ERROR;
/* test whether pattern already contains data. */
/* allocate space if necessary (for new allocated patterns) */
if (pattern -> input_fixsize == 0)
{
pattern -> input_fixsize = NoOfInputUnits;
pattern -> output_fixsize = NoOfOutputUnits;
pattern -> input_dim = 0;
pattern -> output_dim = 0;
KernelErrorCode = kr_np_AllocatePattern(pattern, TRUE);
if (KernelErrorCode == KRERR_NO_ERROR)
KernelErrorCode = kr_np_AllocatePattern(pattern, FALSE);
}
/* modify the copied sub pattern */
if (KernelErrorCode == KRERR_NO_ERROR)
{
KernelErrorCode = kr_np_SetSubPat(TRUE, npui_inpos, npui_insize,
in_pat, NoOfInputUnits);
}
if (KernelErrorCode == KRERR_NO_ERROR)
{
KernelErrorCode = kr_np_SetSubPat(FALSE, npui_outpos, npui_outsize,
out_pat, NoOfOutputUnits);
}
/* free the memory */
if (in_pat != (float *) NULL)
free(in_pat);
if (out_pat != (float *) NULL)
free(out_pat);
return KernelErrorCode;
}
/*****************************************************************************
END OF FILE
******************************************************************************/